
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;



entity rotador3d is
   port(     
      pulsador         : in  std_logic_vector(5 downto 0);    
      xtal             : in  std_logic;
      enable           : in  std_logic;
      Xin              : in  std_logic_vector(14 downto 0);
      Yin              : in  std_logic_vector(14 downto 0);
      Zin              : in  std_logic_vector(14 downto 0);
      Yout             : out std_logic_vector(8 downto 0);
	 	Zout             : out std_logic_vector(8 downto 0);
	 	reset            : out std_logic
   );
end entity;   
architecture R3D of rotador3d is
    
    component FORMATO is
		port(
         clk: in std_logic;
			enable: in std_logic;
	 		Input: in std_logic_vector(14 downto 0);
	 		Output: out std_logic_vector(14 downto 0)
   	);
		end component;
    component FLIP_FLOP_D is
	    generic(
            P: natural
       );
       port(
          clk			: in std_logic;
          input		: in std_logic_vector (P-1 downto 0);
          output		: out std_logic_vector (P-1 downto 0)
   	   );
    end component;
    component MUX_ANGLE is
	    port( 
	      C1 			: in std_logic;
		   C2			 	: in std_logic;
		   OUTPUT 		: out std_logic_vector(8 downto 0)
	    );
    end component;
    component SUMA_ANGLE is
	    port( 
	      I1 			: in std_logic_vector(8 downto 0); --El que es +- 1
		   I2			 	: in std_logic_vector(8 downto 0); --El que se realimenta, comprendido entre -180 y 180
		   O			 	: out std_logic_vector(8 downto 0)
	    );
    end component;
    component CORDIC is
	    port( 
			Xin		 	: in std_logic_vector(14 downto 0); 
		   Yin			: in std_logic_vector(14 downto 0);
		   Zin			: in std_logic_vector(8 downto 0); 
		   Xout		 	: out std_logic_vector(14 downto 0);
		   Yout		 	: out std_logic_vector(14 downto 0)
	);
    end component;
    component CONV_STD_DIR is
       port(
         clk: in std_logic;
         Xstd: in std_logic;
	 		Ystd: in std_logic_vector(14 downto 0);
	 		Zstd: in std_logic_vector(14 downto 0);
	 		Ydir: out std_logic_vector(8 downto 0);
	 		Zdir: out std_logic_vector(8 downto 0)
   	);
   end component;
    
    signal clk_i : std_logic:='0';
    signal p0    : std_logic:='0';
    signal p1    : std_logic:='0';
    signal p2    : std_logic:='0';
    signal p3    : std_logic:='0';
    signal p4    : std_logic:='0';
    signal p5    : std_logic:='0';
    signal ms1   : std_logic_vector(8 downto 0);
    signal ms2   : std_logic_vector(8 downto 0);
    signal ms3   : std_logic_vector(8 downto 0);
    signal alfa  : std_logic_vector(8 downto 0);
    signal beta  : std_logic_vector(8 downto 0);
    signal gama  : std_logic_vector(8 downto 0);
    signal sd1   : std_logic_vector(8 downto 0);
    signal sd2   : std_logic_vector(8 downto 0);
    signal sd3   : std_logic_vector(8 downto 0);
    signal c1    : std_logic_vector(14 downto 0);
    signal c2    : std_logic_vector(14 downto 0);
    signal c3    : std_logic_vector(14 downto 0);
    signal X1    : std_logic_vector(14 downto 0);
    signal Y1    : std_logic_vector(14 downto 0);
    signal Z1    : std_logic_vector(14 downto 0);
    signal Xstd  : std_logic_vector(14 downto 0);
    signal Ystd  : std_logic_vector(14 downto 0);
    signal Zstd  : std_logic_vector(14 downto 0);
    
    begin

		 FORX : FORMATO		  port map (clk_i,enable,Xin,X1);
		 FORY : FORMATO		  port map (clk_i,enable,Yin,Y1);
		 FORZ : FORMATO		  port map (clk_i,enable,Zin,Z1);
       MUX1 : MUX_ANGLE      port map (p5,p4,ms1);
       MUX2 : MUX_ANGLE      port map (p3,p2,ms2);
       MUX3 : MUX_ANGLE      port map (p1,p0,ms3);
       SUM1 : SUMA_ANGLE     port map (ms1,alfa,sd1);
       SUM2 : SUMA_ANGLE     port map (ms2,beta,sd2);
       SUM3 : SUMA_ANGLE     port map (ms3,gama,sd3);
       FFD1 : FLIP_FLOP_D    generic map(9) port map (clk_i,sd1,alfa);
       FFD2 : FLIP_FLOP_D    generic map(9) port map (clk_i,sd2,beta);
       FFD3 : FLIP_FLOP_D    generic map(9) port map (clk_i,sd3,gama);
       CX   : CORDIC         port map (Y1,Z1,alfa,c1,c2);   
       CY   : CORDIC         port map (c2,X1,beta,Zstd,c3);
       CZ   : CORDIC         port map (c3,c1,gama,Xstd,Ystd);
       DIR  : CONV_STD_DIR   port map (clk_i,Xstd(8),Ystd,Zstd,Yout,Zout);
       
       clk_i <= xtal;
       p0    <= pulsador(0);
       p1    <= pulsador(1);
       p2    <= pulsador(2);
       p3    <= pulsador(3);
       p4    <= pulsador(4);
       p5    <= pulsador(5);
       
       reset <= p0 or p1 or p2 or p3 or p4 or p5;
   
end architecture R3D;